import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class JSONDemo {
//    @Test
//    public void fun1(){
////        Demo data = new Demo();
//        Class clazz = Demo.class;
//        Field[] fields = clazz.getDeclaredFields();
//        for (Field field : fields) {
//            System.out.println("O " + field.getName());
//        }
//        Demo data = new Demo();
//        data.setId("IDWWQAC");
//        data.setName("GOD");
//        clazz = data.getClass();
//        fields = clazz.getDeclaredFields();
//        for (Field field : fields) {
//            try {
//                field.setAccessible(true);
//                System.out.println("O " + field.getName() + " " + field.get(data));
//            } catch (IllegalAccessException e) {
//                e.printStackTrace();
//            }
//        }
//    }

    @Test
    public void fun2(){
        Class clazz = Demo.class;
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods){
            System.out.println("O " + method.getName());
        }
    }

    private String toJson(Object object){
        Class clazz = object.getClass();
        Method[]  methods = clazz.getMethods();
        StringBuilder stringBuilder = new StringBuilder("{");
//        String temp = null;
        for(Method method : methods){
            if((method.getName().startsWith("get") && !method.getName().equals("getClass")) || method.getName().startsWith("is")) {
//                System.out.println(method.getName());
                try {
//                    temp = method.invoke(object, null).toString();
//                    System.out.println(temp);
                    stringBuilder.append("\"" + method.getName().substring(3) + "\":\"" + method.invoke(object, null).toString() + "\",");
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        stringBuilder.setCharAt(stringBuilder.length() - 1, '}');
        return stringBuilder.toString();
    }

    private String toJson2(Object object) throws InvocationTargetException, IllegalAccessException {
        Class clazz = object.getClass();
        Method[]  methods = clazz.getMethods();
        StringBuilder stringBuilder = new StringBuilder("{");
        for(Method method : methods){
            if(method.getName().startsWith("get") && !method.getName().equals("getClass")) {
                StringBuilder t = new StringBuilder();
                t.append("\"");
                t.append(method.getName().substring(3));
                t.setCharAt(1, String.valueOf(t.charAt(1)).toLowerCase().charAt(0));
                t.append("\":\"");
                t.append(method.invoke(object, null).toString());
                t.append("\",");
                stringBuilder.append(t);
            }
            if(method.getName().startsWith("is")){
                StringBuilder t = new StringBuilder();
                t.append("\"");
                t.append(method.getName().substring(2));
                t.setCharAt(1, String.valueOf(t.charAt(1)).toLowerCase().charAt(0));
                t.append("\":\"");
                t.append(method.invoke(object, null).toString());
                t.append("\",");
                stringBuilder.append(t);
            }
        }
        stringBuilder.setCharAt(stringBuilder.length() - 1, '}');
        return stringBuilder.toString();
    }

    private String toJson3(Object object){
        Class clazz = object.getClass();
        Method[] methods = clazz.getMethods();
        Field[] fields = clazz.getDeclaredFields();
        List<String> list = new ArrayList<String>();
        StringBuilder stringBuilder = new StringBuilder("{");
        if(fields != null){
            for(Field field : fields){
                list.add(field.getName());
                System.out.println(field.getGenericType().toString());
            }
        }
        if (methods != null) {
            for(Method method : methods){
                if(method.getName().startsWith("get") && !method.getName().equals("getClass")) {
                    StringBuilder t = new StringBuilder();
                    t.append("\"");
                    String temp = findField(list, method.getName().substring(3));
                    if(temp == null){
                        t.append(method.getName().substring(3));
                        t.setCharAt(1, String.valueOf(t.charAt(1)).toLowerCase().charAt(0));
                    }else{
                        t.append(temp);
                    }
                    try {
                        t.append("\":\"");
                        t.append(method.invoke(object, null).toString());
                        t.append("\"");
                    } catch (NullPointerException e){
//                        stringBuilder.setCharAt(stringBuilder.length() - 1, '}');
                        t.setCharAt(t.length() - 1, 'n');
                        t.append("ull");
                    } catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    t.append(",");
                    stringBuilder.append(t);
                }
                if(method.getName().startsWith("is")){
                    StringBuilder t = new StringBuilder();
                    t.append("\"");
                    String temp = findField(list, method.getName().substring(2));
                    if(temp == null){
                        t.append(method.getName().substring(2));
                        t.setCharAt(1, String.valueOf(t.charAt(1)).toLowerCase().charAt(0));
                    }else{
                        t.append(temp);
                    }
                    try {
                        t.append("\":\"");
                        t.append(method.invoke(object, null).toString());
                        t.append("\"");
                    } catch (NullPointerException e){
//                        stringBuilder.setCharAt(stringBuilder.length() - 1, '}');
                        t.setCharAt(t.length() - 1, 'n');
                        t.append("ull");
                    } catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    t.append(",");
                    stringBuilder.append(t);
                }
            }
        }
        if(stringBuilder.length() != 1) {
            stringBuilder.setCharAt(stringBuilder.length() - 1, '}');
        } else {
            stringBuilder.append("}");
        }
        return stringBuilder.toString();
    }

    private String findField(List<String> list, String x){
        for(String temp : list){
            if(temp.toUpperCase().equals(x.toUpperCase())){
                return temp;
            }
        }
        return null;
    }

    @Test
    public void DemoF(){
        Demo demo = new Demo();
        demo.setName("OVEA");
        demo.setId("oooooooo");
        demo.setFlag(true);
        System.out.println(toJson3(demo));
    }

    @Test
    public void Test() throws InvocationTargetException, IllegalAccessException {
        Demo demo = new Demo();
//        demo.setName("OVEA");
//        demo.setId("oooooooo");
//        demo.setFlag(true);
        System.out.println(toJson2(demo));
    }
}

class Demo{
    private String name;
    private String id;
    private Boolean flag;

    public Boolean isFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
